{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 任务返回值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 模板类实现要求：模板类代码必须全部写在头文件中，不能将声明和实现分离。因为模板需要在编译阶段实例化后才能生成真正的函数代码。\n",
    "- `Any`类构造函数：\n",
    "  - 默认构造函数：`Any() = default;`\n",
    "  - 移动构造函数：`Any(Any&&) = default;`\n",
    "  - 删除拷贝构造：`Any(const Any&) = delete;`\n",
    "  - 通用构造函数：`template<typename T> Any(T data)`可以接收任意类型数据\n",
    "- 数据提取方法：\n",
    "  - 使用`dynamic_cast`进行RTTI类型转换\n",
    "  - 类型不匹配时抛出异常\"type is unmatch!\"\n",
    "  - 通过派生类指针访问存储的数据成员`data_`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程执行流"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程执行流的概念\n",
    "\n",
    "- 执行流特点：不同线程拥有独立的执行路径，可能并行或交替执行\n",
    "- 关键问题：当任务执行时间与结果获取时间不匹配时需要同步机制"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "提交任务与执行任务的线程\n",
    "- 线程分工：\n",
    "  - 提交线程：调用`submitTask`方法并立即获得`Result`对象\n",
    "  - 执行线程：线程池中的工作线程实际执行任务\n",
    "- `Result`对象作用：作为任务执行的返回值容器，内部包含`Any`类型存储实际结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任务执行与返回结果\n",
    "\n",
    "- 时序问题：\n",
    "  - 可能情况1：任务未完成时就调用`get()`方法\n",
    "  - 可能情况2：任务完成后很久才调用`get()`方法\n",
    "- 解决方案：需要阻塞机制确保结果可用性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程间的通信与阻塞\n",
    "\n",
    "- 通信模型：\n",
    "  - 提交线程：在`get()`调用处阻塞等待\n",
    "  - 执行线程：任务完成后通知等待线程\n",
    "- 阻塞必要性：保证结果数据的线程安全访问"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程通信的方式\n",
    "\n",
    "- 同步机制分类：\n",
    "  - 互斥：mutex、atomic(CAS)\n",
    "  - 通信：条件变量、信号量\n",
    "- 选择依据：本场景更适合通信机制而非单纯互斥"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "信号量与条件变量的应用\n",
    "\n",
    "- 信号量操作：\n",
    "  - `wait()`：获取资源(可能阻塞)\n",
    "  - `post()`：释放资源(触发通知)\n",
    "- 条件变量对比：同样可以实现类似功能，但信号量更简洁"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "自定义信号量的任务\n",
    "\n",
    "- 实现目标：虽然C++20已提供标准信号量，但自定义实现可以：\n",
    "  - 深入理解底层原理\n",
    "  - 满足特定场景需求\n",
    "- 核心组件：\n",
    "  - 资源计数器`resLimit_`\n",
    "  - 互斥锁`mtx_`\n",
    "  - 条件变量`cond_`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 信号量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 实现基础: 使用互斥锁(mutex)加条件变量(condition variable)组合实现\n",
    "- 资源计数特性:\n",
    "  - 二元信号量(资源计数0/1)与互斥锁功能相同\n",
    "  - 通用信号量资源计数无上限(0,1,2,...n)\n",
    "- 操作机制:\n",
    "  - `wait`操作：资源减1，当资源为0时线程阻塞\n",
    "  - `post`操作：资源加1，唤醒等待线程\n",
    "- 与互斥锁区别:\n",
    "  - 互斥锁必须由获取线程释放\n",
    "  - 信号量可由不同线程操作(`wait/post`)\n",
    "- 应用场景:\n",
    "  - 初始资源为10时，允许10个线程并发访问\n",
    "  - 第11个线程将因资源耗尽而阻塞"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 条件变量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 同步分类:\n",
    "  - 线程互斥:\n",
    "    - 互斥锁(mutex)：重量级锁，会改变线程状态\n",
    "    - CAS原子操作：轻量级，适合简单寄存器-内存数据交换\n",
    "  - 线程通信:\n",
    "    - 条件变量(condition variable)\n",
    "    - 信号量(semaphore)\n",
    "- 原子类型应用:\n",
    "  - atomic头文件提供atomic_int/char/bool等\n",
    "  - 适用于简单原子操作场景\n",
    "- 性能考量:\n",
    "  - 互斥锁系统消耗较大\n",
    "  - CAS不会改变线程状态，效率更高\n",
    "- 实现要点:\n",
    "  - 需要配合整形变量记录资源数量\n",
    "  - 结合互斥锁保证操作原子性"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 信号量类 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "信号量的工作涉及的状态转换 \n",
    "\n",
    "- 实现原理：基于互斥锁和条件变量实现线程间通信\n",
    "- 状态转换：\n",
    "  - 当资源计数`resLimit_>0`时，线程可以获取资源\n",
    "  - 当资源计数`resLimit_=0`时，线程会被阻塞\n",
    "  - 通过`post`操作增加资源计数并通知等待线程\n",
    "  - 通过`wait`操作减少资源计数并可能阻塞线程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "信号量构造函数的实现\n",
    "\n",
    "- 构造函数：\n",
    "  - 默认初始资源计数为0\n",
    "  - 可通过参数指定初始资源数量\n",
    "  - 示例：`Semaphore(int limit = 0) : resLimit_(limit) {}`\n",
    "- 析构函数：\n",
    "  - 使用默认实现：`~Semaphore() = default;`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "信号量方法的实现\n",
    "\n",
    "`wait`方法：\n",
    "- 获取互斥锁保护资源计数\n",
    "- 使用条件变量等待资源可用（`resLimit_>0`）\n",
    "- 资源可用后减少资源计数\n",
    "- 示例代码：\n",
    "\n",
    "`post`方法：\n",
    "- 获取互斥锁保护资源计数\n",
    "- 增加资源计数\n",
    "- 通知所有等待线程资源可用\n",
    "- 示例代码："
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
